package com.dr.cmdb.query.neo4jdao;

import com.dr.cmdb.common.utils.mapper.OrikaMapperUtils;
import com.dr.cmdb.query.neo4jdao.dto.CiItemDto;
import com.dr.cmdb.query.neo4jdao.entity.CiItemEntity;
import com.dr.cmdb.query.neo4jdao.relation.CiItemAssociation;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ProjectName: cmdb
 * @Package: com.dr.cmdb.application.neo4jdao
 * @Description: java类作用描述
 * @Author: duanrui
 * @CreateDate: 2021/4/10 20:27
 * @Version: 1.0
 * <p>
 * Copyright: Copyright (c) 2021
 */
public class RelationTree {

    /**
     * 将关系列表转换成树结构
     *
     * @param rootName
     * @param list
     * @return
     */
    public static CiItemDto getTree(String rootName, List<CiItemAssociation> list) {
        //先找到root节点
        CiItemEntity rootNode = list.stream().map(CiItemAssociation::getSource).filter(source -> source.getName().equals(rootName)).findFirst().orElse(null);
        if (null == rootNode) {
            return null;
        }
        Map<String, List<CiItemEntity>> nodeListMap = getNodeList(list);
        CiItemDto root = OrikaMapperUtils.map(rootNode, CiItemDto.class);
        List<CiItemEntity> parentList = nodeListMap.get(rootName);
        List<CiItemDto> ciItems = OrikaMapperUtils.mapList(parentList, CiItemEntity.class, CiItemDto.class);
        root.setChildren(ciItems);
        //排除root节点
        ciItems.remove(rootNode);
        loadChildren(nodeListMap, ciItems);
        return root;

    }

    /**
     * @date:2021/4/12
     * @className:RelationTree
     * @author:duanrui
     * @description: 拼接结果
     */
    private static Map<String, List<CiItemEntity>> getNodeList(List<CiItemAssociation> list) {
        Map<String, List<CiItemEntity>> resultMap = new HashMap<>(list.size());
        Map<String, List<CiItemAssociation>> map = list.stream().collect(Collectors.groupingBy(e -> e.getSource().getName()));
        map.forEach(
                (k, v) -> {
                    resultMap.put(k, v.stream().map(CiItemAssociation::getTarget).collect(Collectors.toList()));
                }
        );
        return resultMap;
    }

    /**
     * @date:2021/4/11
     * @className:RelationTree
     * @author:Administrator
     * @description: 递归构建树
     */
    private static void loadChildren(Map<String, List<CiItemEntity>> map, List<CiItemDto> parentList) {
        parentList.forEach(
                e -> {
                    List<CiItemEntity> subList = map.get(e.getName());
                    if (!CollectionUtils.isEmpty(subList)) {
                        List<CiItemDto> ciItems = OrikaMapperUtils.mapList(subList, CiItemEntity.class, CiItemDto.class);
                        e.setChildren(ciItems);
                        // 设置子节点
                        loadChildren(map, ciItems);
                    }
                }
        );
    }


}
